Unityでプラグイン機構を持ったdllを作る


概要

次のような前提の時に使えるテクニック。


・dllにして配布するAssetを作る

・プロジェクト内に特定のdllがある場合、それを本Assetから拡張機能として使う


例えば、「もしAっていうライブラリがあったら、それを使った拡張機能を有効にする」みたいなやつ。

これは変則的だけど、「他のライブラリをプラグインのように扱う」ってことになる。



具体例

UUebViewっていうAsset作って使ってるんだけど、デフォルトではuGUIのテキストを使ってUIを生成している。


で、まあ、テキストといえばTextMesh Pro(TMPro)で、そっち使った方が綺麗なUIになるんだよね。

なので、TMProを使った描画機能を提供したい。


TMPro、予定ではUnityに組み込まれ中というステータスなんだけど、現状ではまだ含まれていない。

AssetStoreで無料で取得できるけど、勝手にプロジェクトにdllを組み込むわけにはいかない。


よって、次のような条件が存在する。

1.TMProがあったらTMProの機能を使って描画する機能がOnになる

2.verとか重複で絶対困るので、TMProのdllを組み込んで配布するわけにはいかない = AssetのdllにTMProを含めてはいけない

3.TMProがなかったらその機構は使えないが、それはそれとしてuGUI Textが使えるので単体でビルドできないといけない

4.できるだけコンパイル時にTMProを使うかどうかの選択を完了させたい。


つまり、TMProを含まず、TMProが場にあった場合にはそちらに接続することができ、

TMProがない場合でも動作してほしくて、コンパイル時には何を使うか確定していると楽。



叶え方

真面目にリフレクションなどで実行時にガンバるみたいな手もあったんだけど、できるだけコンパイル時に完了させたい。

ということでこんな感じにすればできるよ的な。



・本体コード -> 依存対象dllへの依存があるコードを書く

・依存対象dllを一旦削除し、依存対象dllに入っていた部分をダミーコードとして実装する

・ダミーコードを依存対象と同じsignatureでdllにする(ダミーdllの生成)

・ダミーdllを参照する形で本体コードをdllへとコンパイル(本体dllの生成)


これで、ダミーdll = 依存対象dll という関係が成立し、本体dllからは、ダミーdllと依存対象dllの区別はつかず、

依存対象dllの機能を本体dllから使いたい場合は、ダミーdllを削除 & 依存対象dllをコンパイルに巻き込めばOK という形になる。


問題点

TMProのdllのsignatureが最悪で、次のような値になっている。


Assembly TextMeshPro-2017.2-1.0.56-Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null


nameにversion値が書いてあるんで頭を抱えている。

これ新version出たらdllのsignature変わってしまうので、適合性が消えてしまう。


で、これはまあ対処法としては、本体dllに記載されている「こんな名前のdllに依存してます」みたいな情報を書き換えるとできる。

その機能をポータブルに提供できれば、完璧なのだが。


まだそこまでは踏み込んでいない。


いろいろ解決できたらさらに図を足す。